<?php
namespace app\lib;
/**
 * xml转化为数组
 * Class Xml2Array
 * User:于小涛
 * Date:2020/2/23
 * Time:20:32
 */
class Xml2Array {

    private static $arr_re=array(
        0=>array(
            'code'=>0,
            'reason'=>'成功',
        ),
        1=>array(
            'code'=>1,
            'reason'=>'解析失败',
        ),
    );
    /**
     * @param string $str_xml xml字符串
     * @return array 转化后的数组array('ret'=>返回编码,'reason'=>编码解释,'data'=>解析后的数组)
     */
    static function getArrayData($str_xml = null) {
        $obj_node = @simplexml_load_string($str_xml, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
        if ($obj_node === false) {
            $arr_re = self::$arr_re[1];
        } else {
            $arr_re = self::$arr_re[0];
            $arr_re['data']=self::parseNode($obj_node);
        }
        return $arr_re;
    }

    /**
     * 解析SimpleXMLElement节点对象
     * @param SimpleXMLElement $obj_node 需要解析的几点
     * @param array $arr_parent 本次递归返回的数组
     * @param string $str_namespace 命名空间
     * @param bool $bool_recursive 是否是递归
     * @return array
     */
    private static function parseNode($obj_node, &$arr_parent = null, $str_namespace = '', $bool_recursive = false) {
        $arr_namespaces = $obj_node->getNameSpaces(true);
        $str_content = "{$obj_node}";
        $arr_children['name'] = $obj_node->getName();
        if (!$bool_recursive) {
            $tmp = array_keys($obj_node->getNameSpaces(false));
            $arr_children['namespace'] = $tmp?$tmp[0]:'';
            $arr_children['namespaces'] = $arr_namespaces;
        }
        if ($str_namespace) {
            $arr_children['namespace'] = $str_namespace;
        }
        if (isset($str_content)) {
            $arr_children['content'] = $str_content;
        }
        foreach ($arr_namespaces as $pre => $ns) {
            $_obj_xml_node = $obj_node->children($ns);
            foreach ($_obj_xml_node as $k => $v) {
                self::parseNode($v, $arr_children['children'], $pre, true);
            }
            $_boj_xml_attributes = $obj_node->attributes($ns);
            foreach ($_boj_xml_attributes as $k => $v) {
                $arr_children['attributes'][$k] = "$pre:$v";
            }
        }
        foreach ($obj_node->children() as $k => $v) {
            self::parseNode($v, $arr_children['children'], '', true);
        }
        foreach ($obj_node->attributes() as $k => $v) {
            $arr_children['attributes'][$k] = "$v";
        }
        $arr_parent[] = &$arr_children;
        return $arr_parent[0];
    }


    static public function getXmlData($arr_data)
    {
        $obj_xlm=new SimpleXMLElement("<?xml version='1.0'?><{$arr_data['name']}></{$arr_data['name']}>");
        self::_create_xml($obj_xlm,$arr_data['children']);

        return $obj_xlm->saveXML();
    }

    private static function _create_xml($obj_xlm,$arr_data)
    {
        $i=0;
        foreach($arr_data as $arr_child)
        {
            $obj_xml_child=$obj_xlm->addChild($arr_child['name']);
            if(isset($arr_child['val'])&&!empty($arr_child['val']))
            {
                $obj_current=$obj_xlm->$arr_child['name'];
                $obj_current[$i]=$arr_child['val'];
            }
            if(is_array($arr_child['attributes']))
            {
                foreach($arr_child['attributes'] as $str_attr=>$str_val)
                {
                    $obj_xml_child->addAttribute($str_attr,$str_val);
                }
            }
            if(is_array($arr_child['children'])&&!empty($arr_child['children']))
            {
                self::_create_xml($obj_xml_child,$arr_child['children']);
            }
            $i++;
        }
    }
}
/*$obj=new np_xml2array();
    $arr_data=array (
        'name' => 'service',
        'namespace' => NULL,
        'namespaces' =>
            array (
            ),
        'children' =>
            array (
                0 =>
                    array (
                        'name' => 'category',
                        'val'=>'ddd',
                        'attributes' =>
                            array (
                                'id' => '10000001',
                                'name' => '电影',
                                'parent' => '0',
                            ),
                    ),
                11 =>
                    array (
                        'name' => 'category',
                        'children' =>
                            array (
                                0 =>
                                    array (
                                        'name' => 'category',
                                        'val'=>'daaaa',
                                        'attributes' =>
                                            array (
                                                'id' => '10000015222',
                                                'name' => '广告子栏目',
                                                'parent' => '10000015',
                                            ),
                                    ),
                            ),
                        'attributes' =>
                            array (
                                'id' => '10000015',
                                'name' => '广告',
                                'parent' => '0',
                            ),
                    ),
                22 =>
                    array (
                        'name' => 'category',
                        'attributes' =>
                            array (
                                'id' => '10000091',
                                'name' => '原创',
                                'parent' => '0',
                            ),
                    ),
            ),
    );
    header("Content-type:text/xml");
    $obj->getXmlData($arr_data);*/